package com.mall.common.core.utils;

import com.mall.common.core.cons.APICons;
import com.mall.common.core.model.log.SysLog;
import com.mall.common.core.model.response.ApiResponses;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Objects;
import java.util.Optional;

/**
 * 请求日志工具类
 *
 * @author Sam
 */
@Slf4j
public abstract class LogUtils {

    /**
     * 获取日志对象 输出Info日志
     */
    public static void printInfoLog(HttpServletRequest request, Object obj) {
        SysLog logInfo = SysLog.builder()
                //查询参数
                .parameterMap(request.getParameterMap())
                //请求体
                .requestBody(Optional.ofNullable(JacksonUtils.parse(RequestUtils.getRequestBody(request))).orElse(RequestUtils.getRequestBody(request)))
                //请求路径
                .url((String) request.getAttribute(APICons.API_REQURL))
                //请求名
                .name((String) request.getAttribute(APICons.API_NAME))
                //请求方法
                .method((String) request.getAttribute(APICons.API_METHOD))
                //响应体
                .result(obj)
                //运行时间
                .runTime((request.getAttribute(APICons.API_BEGIN_TIME) != null ? System.currentTimeMillis() - (Long) request.getAttribute(APICons.API_BEGIN_TIME) : 0) + "ms")
                //ip地址
                .ip(IpUtils.getIpAddr(request))
                //操作类型
                .operType(TypeUtils.castToString(request.getAttribute(APICons.API_OPER_TYPE)))
                //操作人
                .operName(TypeUtils.castToString(request.getAttribute(APICons.API_OPER_NAME)))
                .build();
        log.info(JacksonUtils.toJson(logInfo));
    }

    /**
     * 获取日志对象  输出Error日志
     */
    public static void printExLog(HttpServletRequest request, ApiResponses failure, Exception e) {
        SysLog errInfo = SysLog.builder()
                //查询参数
                .parameterMap(request.getParameterMap())
                //请求体
                .requestBody(Optional.ofNullable(JacksonUtils.parse(RequestUtils.getRequestBody(request))).orElse(RequestUtils.getRequestBody(request)))
                //请求路径
                .url((String) request.getAttribute(APICons.API_REQURL))
                //请求名
                .name((String) request.getAttribute(APICons.API_NAME))
                //请求方法
                .method((String) request.getAttribute(APICons.API_METHOD))
                //响应体
                .result(failure)
                //异常信息
//                .errMsg(Throwables.getStackTraceAsString(e))
                //运行时间
                .runTime((request.getAttribute(APICons.API_BEGIN_TIME) != null ? System.currentTimeMillis() - (Long) request.getAttribute(APICons.API_BEGIN_TIME) : 0) + "ms")
                //ip地址
                .ip(IpUtils.getIpAddr(request))
                //操作类型
                .operType(TypeUtils.castToString(request.getAttribute(APICons.API_OPER_TYPE)))
                //操作人
                .operName(TypeUtils.castToString(request.getAttribute(APICons.API_OPER_NAME)))
                .build();
        log.error(JacksonUtils.toJson(errInfo));
        log.error("Error: doResolveException!", Objects.nonNull(e.getCause()) ? e.getCause() : e);
    }

    /**
     * 第三方设备异常Log
     * 如 msg:redis挂掉了 component redis
     * 输出: redis挂掉了(redis)
     *
     * @param msg
     * @param component
     */
    public static void errorLog(String msg, String component) {
        log.error(msg + "(" + component + ")");
    }

    //默认文件路径
    private final static String PATH = System.getProperty("user.dir") + "/logs/demo";
    public final static String MESSAGE_LOG = "/runBroken.log";

    /**
     * 写日志文件 默认路径
     *
     * @param str 日志内容
     */
    public static void writeLog(String str) {
        try {
            File file = new File(PATH + MESSAGE_LOG);
            existsFile(file);
            FileOutputStream out = new FileOutputStream(file, true);
            StringBuffer sb = new StringBuffer();
            sb.append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            sb.append("\t");
            sb.append(str);
            sb.append("\r\n");
            out.write(sb.toString().getBytes(StandardCharsets.UTF_8));
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 写日志文件 指定路径
     *
     * @param str  日志内容
     * @param path 日志文件路径
     */
    public static void writeLog(String str, String path) {
        try {
            File file = new File(PATH + path);
            existsFile(file);
            FileOutputStream out = new FileOutputStream(file, true);
            StringBuffer sb = new StringBuffer();
            sb.append(LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
            sb.append("\t");
            sb.append(str);
            sb.append("\r\n");
            out.write(sb.toString().getBytes(StandardCharsets.UTF_8));
            out.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 是否存在该路径/文件
     *
     * @param file
     * @throws IOException
     */
    private static void existsFile(File file) throws IOException {
        File parentFile = file.getParentFile();
        if (!parentFile.exists()) {
            parentFile.mkdirs();
        }
        if (!file.exists()) {
            file.createNewFile();
        }
    }
}
